/*
 * Copyright (C) 2009 IMOBISOFT Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package imobisoft.android.hialarm.base;

import java.lang.reflect.Method; 

import android.content.BroadcastReceiver; 
import android.content.Context; 
import android.content.Intent; 
import android.content.IntentFilter; 
import android.util.Log; 

public class BTDevice { 
     private static final String TAG = "BTDevice"; 

     public static final String ENABLED_ACTION = "android.bluetooth.intent.action.ENABLED"; 
     public static final String DISABLED_ACTION = "android.bluetooth.intent.action.DISABLED"; 

     private final Context mContext; 
     private Object mDevice; 
     private Method mEnable; 
     private Method mDisable; 
     private Method mIsEnabled; 
     private IntentFilter mIntentFilter; 
     private boolean mWaitState; 
     private boolean mIsBusy = false; 

     public BTDevice(Context context) { 
          mContext = context; 
          try { 
               mDevice = mContext.getSystemService("bluetooth"); 
               if (mDevice != null) { 
                    Class<?> c = mDevice.getClass(); 
                    mEnable = c.getMethod("enable"); 
                    mEnable.setAccessible(true); 
                    mDisable = c.getMethod("disable"); 
                    mDisable.setAccessible(true); 
                    mIsEnabled = c.getMethod("isEnabled"); 
                    mIsEnabled.setAccessible(true); 
               } 
               mIntentFilter = new IntentFilter(BTDevice.ENABLED_ACTION); 
               mIntentFilter.addAction(BTDevice.DISABLED_ACTION); 
               mIsBusy = false; 
          } catch (Exception e) { 
               e.printStackTrace(); 
          } 
     } 

     /** 
      * Requests for the device to be enabled. Returns true if the request is 
      * successful, but it does not mean that the device was successfully 
      * enabled. You will be notified via the OnChangeListener when the device's 
      * state is actually changed. 
      */ 
     public boolean enable() { 
          try { 
               if ((Boolean) mEnable.invoke(mDevice) == true) { 
                    mIsBusy = true; 
                    mWaitState = true; 
               } 
               callOnChangeListener(); 
          } catch (Exception e) { 
               e.printStackTrace(); 
          } 
          return mIsBusy; 
     } 

     /** 
      * Requests for the device to be disabled. Returns true if the request is 
      * successful, but it does not mean that the device was successfully 
      * disabled. You will be notified via the OnChangeListener when the device's 
      * state is actually changed. 
      */ 
     public boolean disable() { 
          try { 
               if ((Boolean) mDisable.invoke(mDevice) == true) { 
                    mIsBusy = true; 
                    mWaitState = false; 
               } 
               callOnChangeListener(); 
          } catch (Exception e) { 
               e.printStackTrace(); 
          } 
          return mIsBusy; 
     } 

     /** 
      * Requests for the device's power state to be toggled. Returns true if the 
      * request is successful, but it does not mean that the device was 
      * successfully toggled. You will be notified via the OnChangeListener when 
      * the device's state is actually changed. 
      */ 
     public boolean toggle() { 
          if (isEnabled()) 
               return disable(); 
          else 
               return enable(); 
     } 

     /** 
      * Returns true if the device is currently enabled. 
      */ 
     public boolean isEnabled() { 
          boolean bEnabled = false; 
          try { 
               bEnabled = (Boolean) mIsEnabled.invoke(mDevice); 
          } catch (Exception e) { 
               e.printStackTrace(); 
          } 
          return bEnabled; 
     } 

     /** 
      * Returns true if the device is in the process of being enabled/disabled. 
      */ 
     public boolean isBusy() { 
          return mIsBusy; 
     } 

     /** 
      * Returns a string describing the current status of the device if it is 
      * busy. 
      */ 
     public String getStatus() { 
          String str = null; 
          if (isBusy()) { 
               if (mWaitState == true) 
                    str = "Enabling..."; 
               else 
                    str = "Disabling..."; 
          } 
          return str; 
     } 

     /** 
      * Be sure to call pause() whenever your Activity is paused. 
      */ 
     public void pause() { 
          mContext.unregisterReceiver(mBluetoothReceiver); 
     } 

     /** 
      * Be sure to call resume() whenever your Activity is paused. 
      */ 
     public void resume() { 
          mContext.registerReceiver(mBluetoothReceiver, mIntentFilter); 
     } 

     /** 
      * Register this BroadcastReceiver to be notified of whenever Bluetooth is 
      * enabled/disabled 
      */ 
     private final BroadcastReceiver mBluetoothReceiver = new BroadcastReceiver() { 
          @Override 
          public void onReceive(Context context, Intent intent) { 
               String action = intent.getAction(); 
               if (action.equals(BTDevice.ENABLED_ACTION)) { 
            	   Log.d(AlarmConst.TAG,BTDevice.ENABLED_ACTION);
               } else if (action.equals(BTDevice.DISABLED_ACTION)) { 
            	   Log.d(AlarmConst.TAG,BTDevice.DISABLED_ACTION);
               } 
               mIsBusy = false; 
               callOnChangeListener(); 
          } 
     }; 

     /** 
      * Listener used to dispatch state change events. 
      */ 
     protected OnChangeListener mOnChangeListener = null; 

     /** 
      * Call this device's OnChangeListener, if it is defined. 
      */ 
     protected void callOnChangeListener() { 
          if (mOnChangeListener != null) { 
               mOnChangeListener.onChange(this); 
          } 
     } 

     /** 
      * Register a callback to be invoked when this device's state changes. 
      * 
      * @param l 
      *            The callback that will run 
      */ 
     public void setOnChangeListener(OnChangeListener l) { 
          mOnChangeListener = l; 
     } 

     /** 
      * Interface definition for a callback to be invoked when the device's state 
      * changes. 
      */ 
     public interface OnChangeListener { 
          /** 
           * Called when the device's state changes. 
           * 
           * @param d 
           *            The device that has changed. 
           */ 
          void onChange(BTDevice d); 
     } 
} 